﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>3D Viewer</title>

    <script src="FileUtils.js"></script>
    <script src="Resources.js"></script>
    <script src="ResourcesFile.js"></script>
    <script src="Tracks.js"></script>
    <script src="babylon.2.0.js"></script>
    <script src="objects.js"></script>

    <style>
        html, body {
            width: 100%;
            height: 100%;
            padding: 0;
            margin: 0;
            overflow: hidden;
        }
        #renderCanvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="renderCanvas"></canvas>
</body>

<script>
    function addEventHandler(obj, evt, handler) {
        if (obj.addEventListener) {
            // W3C method
            obj.addEventListener(evt, handler, false);
        } else if (obj.attachEvent) {
            // IE method.
            obj.attachEvent('on' + evt, handler);
        } else {
            // Old school method.
            obj['on' + evt] = handler;
        }
    }

    if (BABYLON.Engine.isSupported()) {
        var canvas = document.getElementById("renderCanvas");
        var engine = new BABYLON.Engine(canvas, true);

        var scene = new BABYLON.Scene(engine);
        var materials = Resources.Material.CreateMaterials(scene)

        var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 500, 0), scene);
        camera.attachControl(canvas, true);
        camera.checkCollisions = true;
        camera.speed = 30;
        camera.keysDown = [40];
        camera.keysUp = [38];
        camera.keysLeft = [37];
        camera.keysRight = [39];

        var light1 = new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(0, 1, 1), scene);
        light1.diffuse = new BABYLON.Color3(1, 1, 1);
        light1.specular = new BABYLON.Color3(1, 1, 1);
        scene.lights.push(light1);

        function readTrack(trackFile) {
            var stuntTrack = new Tracks.StuntTrack();
            var track = stuntTrack.Read(trackFile);
            displayTrack(track);
        }

        function displayTrack(track) {
            scene.meshes = [];
            var tilesize = 300
            camera.position.x = track.SizeX * tilesize / 2;
            camera.position.y = 500;
            camera.position.z = -track.SizeY * tilesize - 500;

            //camera.cameraDirection.x = 0;
            //camera.cameraDirection.y = -.25;
            //camera.cameraDirection.z = -track.SizeY * tilesize / 2;

            shape = new BABYLON.Mesh("ground", scene);
            var indices = [];
            var positions = [];
            var normals = [];
            var uvs = [];
            positions.push(0.00, -1.00, 0.00);
            normals.push(0.00, -1.00, 0.00);
            positions.push(track.SizeX * 300, -1.00, 0.00);
            normals.push(0.00, -1.00, 0.00);
            positions.push(0.00, -1.00, -track.SizeY * 300);
            normals.push(0.00, -1.00, 0.00);
            positions.push(track.SizeX * 300, -1.00, -track.SizeY * 300);
            normals.push(0.00, -1.00, 0.00);
            indices.push(0, 1, 3);
            indices.push(0, 3, 2);
            shape.setVerticesData(positions, BABYLON.VertexBuffer.PositionKind);
            shape.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind);
            shape.setIndices(indices);
            shape.material = materials[2];
            scene.meshes.push(shape);

            //for (var x=0; x<track.SizeX;x++) {
            //    var line = shape = BABYLON.Mesh.CreateLines("lX" + x, [new BABYLON.Vector3(x * tilesize, 10, 0), new BABYLON.Vector3(x * tilesize, 10, -track.SizeX * tilesize)], scene)
            //    var line = shape = BABYLON.Mesh.CreateLines("lX" + x, [new BABYLON.Vector3(0, 10, -x * tilesize), new BABYLON.Vector3(track.SizeX * tilesize, 10, -x * tilesize)], scene)
            //}

            for (var x = 0; x < track.SizeX; x++) for (var y = 0; y < track.SizeY; y++) {

                var el = track.Elements[x][y];

                var terrainImg = Tracks.TerrainTiles[el.Terrain];
                var trackImg = Tracks.TrackTiles[el.Obj];
                var replaceTerrain = false;

                if (terrainImg != null) {
                    for (var obj in terrainImg.Objects) {
                        var object = terrainImg.Objects[obj];
                        var elements = object.Elements;
                        for (var element in elements) {
                            var shapes = shapesBuilders[elements[element]];
                            if (shapes == null) continue;
                            var mesh = new shapes(scene);
                            var tileInfo = terrainImg.Objects[obj];
                            mesh.position.x = x * tilesize + tileInfo.ShiftX(300);
                            mesh.position.z = -y * tilesize - tileInfo.ShiftY(300);
                            mesh.position.y = terrainImg.TerrainHeight;
                            mesh.rotation.y = tileInfo.Orientation;
                            scene.meshes.push(mesh);
                        }
                    }
                }

                if (trackImg != null) {
                    var objects = [];
                    var replacement = false;
                    for (var obj in trackImg.Objects) {
                        var object = trackImg.Objects[obj];
                        if (object.IsReplacement && object.Terrain == el.Terrain) {
                            if (!replacement) {
                                replacement = true
                                objects = [];
                            }
                            objects.push(object);
                        } else if (!replacement && !object.IsReplacement) {
                            objects.push(object);
                        }
                    }
                    for (var obj in objects) {
                        var object = objects[obj]
                        for (var element in object.Elements) {
                            var shapes = shapesBuilders[object.Elements[element]];
                            if (shapes == null) continue;
                            var mesh = new shapes(scene);
                            var tileInfo = trackImg.Objects[obj];
                            mesh.position.x = x * tilesize + object.ShiftX(tilesize);
                            mesh.position.z = -y * tilesize - object.ShiftY(tilesize);
                            mesh.position.y = terrainImg.ObjectsHeight + (replaceTerrain ? 0.00 : 1.00);
                            mesh.rotation.y = object.Orientation;
                            scene.meshes.push(mesh);
                        }
                    }
                }


            }

        }

        // Render loop
        var renderLoop = function () {
            scene.render();
        };

        // Launch render loop
        engine.runRenderLoop(renderLoop);


        if (window.FileReader) {
            addEventHandler(window, 'load', function () {
                var drop = document.getElementById('renderCanvas');

                function cancel(e) {
                    if (e.preventDefault) { e.preventDefault(); }
                    return false;
                }

                // Tells the browser that we *can* drop on this target
                addEventHandler(drop, 'dragover', cancel);
                addEventHandler(drop, 'dragenter', cancel);

                addEventHandler(drop, 'drop', function (e) {
                    e = e || window.event; // get window.event if e argument missing (in IE)   
                    if (e.preventDefault) { e.preventDefault(); } // stops the browser from redirecting off to the image.

                    var dt = e.dataTransfer;
                    var files = dt.files;
                    var file = files[0];

                    FileUtils.Reader.ReadBlob(file, readTrack);

                    return false;
                });
            });
        } else {
            document.getElementById('status').innerHTML = 'Your browser does not support the HTML5 FileReader.';
        }


    }
</script>
</html>